- /* smmreadn.cpp by K.Tsuru */
- // function ID = 005, 006 DRADIX
- #ifndef SN_H
- #include "sn.h"
- #endif
- /****************************************************************************
- SNManager class
- ReadNumber
- Read a SNumber data from a file.
- It reads number(s) such as integer, fraction or real from a file and returns
- the pointer to constant literal.If you want to receive it as a literal please
- write such as
- const char* str;
- str = SNManager::ReadNumber(fname);
- If you want a direct substitution
- SLong a;
- a = a.ReadNumber(fname);
- a.CloseReadNumber();
- [Notes on making files]
- Comment is allowed to insert.However the first character must be an alphabet,
- namely the line which begins with an alphabet is passed to the end.If the
- designated file cannot be opened or is not a number file it abnormally
- terminates the program. It can read "maxDigits"(defined in memblock.h) degits at
- the maximum.
-
- ----- An example of continuous read. --------
- SLong f, r;
- const char* num = f.ReadNumber(fname);
-
- while(num != NULL){
- r = num;
- r.Puts();
- num = r.ReadNumber(NULL);
- }
- ****************************************************************************/
-
- /**** static objects and functions *******************************************/
-
- static char* readBuff = NULL;
- static FILE* readStream = NULL;
- static int openFile = -1;
-
- // '/', '(', ')': for SFraction
- static const char* ok = " +-/.eE"; //the list of character for the number
- static const char* skip = " \\()\n\r"; //the list of character for the skip
-
- enum{ NUM_END = 1, SKIP, VALID};
-
- static void CloseReadFile(){
- if(readStream != NULL) fclose(readStream);
- openFile = 0; readStream = NULL;
- }
-
- // function ID = 006
- void SNManager::CloseReadNumber(){
- if(openFile < 0) return;
- CloseReadFile(); openFile = -1;
- delete[] readBuff; readBuff = NULL;
- }
-
- // fs : file or character's information.
- static int ReadDigit(int* fs){
- int c = fgetc(readStream);
- *fs = VALID;
- if( strchr(skip, c) != NULL ) *fs = SKIP;
- else if(c == EOF) *fs = EOF; //This must have priority over the following.
- else if(!isdigit(c) && (strchr(ok, c) == NULL)) *fs = NUM_END;
-
- return c;
- }
- //search the beginning of number
- static int SearchBegin(){
- const char* const begin = "+-."; //character set of bigining of number except digit
- int c;
- do{
- c = fgetc(readStream);
- if(isalpha(c)){ // A comment begins.
- while(1){
- c = fgetc(readStream);
- if( (c == '\n') || (c == '\r' ) || (c == EOF) ) break;
- }
- }
- } while(!isdigit(c) && (strchr(begin, c) == NULL) && (c != EOF));
-
- if(c != EOF) ungetc(c, readStream); //push back by a character
- return c;
- }
-
- static ulong NumLength(ulong maxLen){ // ver. 2.17, change "long" to "ulong"
- ulong len = 0; // It is remaked to partially read up to "maxLen".
- long top = ftell(readStream);
- int k;
-
- if(maxLen == 0) maxLen = ULONG_MAX;
- while(1){
- ReadDigit(&k);
- if( (k == EOF) || (k == NUM_END) || (len == maxLen) ) break;
- if(k != SKIP) len++;
- }
- fseek(readStream, top, SEEK_SET); // Restore file pointer.
- return len;
- }
-
- /*** Main body ********************************************************/
- // function ID = 005
-
- const char* SNManager::ReadNumber(const char* fname, uint size, int del){
- delete[] readBuff;
- readBuff = NULL; //Considering continuous call it frees memory first.
-
- if(fname != NULL){
- CloseReadFile(); // close previous file
- readStream = fopen(fname, "rt");
- if(readStream == NULL){
- fprintf(stderr, "Cannot open file : %s.\n", fname);
- exit(EXIT_FAILURE);
- }
- } else if(readStream == NULL){
- // fname == NULL the error of usage of continuous reading
- fprintf(stderr, "Did not open a number file yet.\n");
- exit(EXIT_FAILURE);
- }
-
- if( SearchBegin() == EOF){
- if(openFile <= 0){
- fprintf(stderr, "%s is not a number file.\n", fname);
- exit(EXIT_FAILURE);
- }
- CloseReadNumber();
- return NULL;
- }
-
- ulong readSize = (ulong)size*(ulong)DFIGURES, len = 0;
- ulong fsize = NumLength(readSize); //By reading through the file it gets the length.
-
- if(size && (fsize > readSize) ) fsize = readSize;
- if(fsize + 1uL > maxDigits) SetError(TOO_LONG,"ReadNumber", 5);//"maxDigits" in "membock.h"
-
- readBuff = new char[(uint)fsize+1]; // fsize + 1 <= UINT_MAX
-
- int c, k;
- while(1){
- c = ReadDigit(&k);
- if( (k == EOF) || (k == NUM_END) || (len == fsize) ){
- readBuff[len] = '\0';
- break;
- }
- if(k != SKIP) readBuff[len++] = (char)c;
- }
- if( size && (k != NUM_END) ){ //pass to the top of next data
- while(1){
- c = ReadDigit(&k);
- if( (k == EOF) || (k == NUM_END) ) break;
- }
- }
- if(k != EOF){ // data remains
- ungetc(c, readStream); // push back a character
- openFile = 1;
- } else CloseReadFile(); // set "openFile = 0"
-
- if(del && (fname != NULL) ){
- CloseReadFile();
- if( remove(fname) ) perror("Delete file");
- }
- return readBuff;
- }
-
smmreadn.cpp : last modifiled at 2017/06/23 10:37:54(4,952 bytes)
created at 2016/04/11 11:36:47
The creation time of this html file is 2017/10/27 10:59:17 (Fri Oct 27 10:59:17 2017).